/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kotionokyurievna.gmail.com.callablethreads.threadPack;

import java.lang.Integer;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 *
 * @author Kateryna_Reznik
 */
public class ThreadExecutorMain {
    private int threadCount;
    private int[] arrayToCalculate;
    private double sum;
    
    public ThreadExecutorMain( int threadCount, int[] argumentsArray){
        setThreadCount(threadCount);
        int arLength = argumentsArray.length;
        arrayToCalculate = new int[arLength];
        System.arraycopy(argumentsArray, 0, arrayToCalculate, 0, arLength);
        sum = 0;
    }
    
      
    public void setThreadCount( int threadNum){
        if ( threadNum > 0 ){
            threadCount = threadNum;
        }
        else{
            threadCount = 1;
        }
    }
    
    public double divideTask(){
        ArrayList<SimpleThread> runnablePool = new ArrayList<>();
        SimpleThread sThread;
        
        int n = arrayToCalculate.length;
        int from = 0;
        int to = 0;
        int nTasks = 0;
        int tasks[][] = new int [threadCount][];
        for ( int i = 0; i < threadCount; i++ ){
            from = i * n / threadCount;
            to = (i + 1) * n / threadCount;
            nTasks = to - from;
            tasks[i] = new int[nTasks];
            System.arraycopy(arrayToCalculate, from, tasks[i], 0, nTasks);
            sThread = new SimpleThread(tasks[i], i);
            runnablePool.add(sThread);
        }
        
        ExecutorService executor = Executors.newCachedThreadPool();
        Set<Future<Double>> set = new HashSet<Future<Double>>();
        for ( SimpleThread st: runnablePool ){
            Future<Double> future = executor.submit(st);
            set.add(future);
        }
        executor.shutdown();
        
         double sum = 0;
         for (Future<Double> future : set) {
             try {
                sum += future.get();
            }
            catch ( InterruptedException ex ){
                System.out.println(ex);
            }   
            catch ( ExecutionException eex){
                System.out.println(eex);
            }
         }
        return sum;
                
    }
       
    
    public boolean equals ( Object obj ){
	if ( obj != null && getClass() == obj.getClass() ){
            ThreadExecutorMain other = (ThreadExecutorMain) obj;
            return ( other.threadCount == threadCount);
	}
	return false;
    }
    
    
}
